﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace CommonTagTime
{
    public class clsImage
    {
        public int pWidth
        {
            get { return _pWidth; }
            set { _pWidth = value; }
        }

        public int pHeight
        {
            get { return _pHeight; }
            set { _pHeight = value; }
        }

        private int _pWidth = 0;
        private int _pHeight = 0;

        public static bool ThumbnailCallback() { return false; }

        public static byte[] CreateImageThumbnail(byte[] data, string contentType, int height, int width, bool stretch)
        {
            MemoryStream stream = new MemoryStream(data);
            return CreateImageThumbnail(stream, contentType, height, width, stretch);
        }

        public static byte[] CreateImageThumbnail(Stream stream, string contentType, int height, int width, bool stretch)
        {
            stream.Position = 0;

            Bitmap image = (Bitmap)Bitmap.FromStream(stream, true);

            //Bitmap image = new Bitmap(data);
            int widthTh, heightTh; float widthOrig, heightOrig;
            float fx, fy, f;

            if (!stretch)
            {
                // retain aspect ratio
                widthOrig = image.Width;
                heightOrig = image.Height;
                fx = widthOrig / width;
                fy = heightOrig / height; // subsample factors

                // must fit in thumbnail size
                f = Math.Max(fx, fy); if (f < 1) f = 1;
                widthTh = (int)(widthOrig / f); heightTh = (int)(heightOrig / f);
            }
            else
            {
                widthTh = width; heightTh = height;
            }

            // We got here, so we do want to scale it.
            Graphics graph;
            Bitmap bitmap = new Bitmap(widthTh, heightTh);
            graph = Graphics.FromImage(bitmap);
            graph.InterpolationMode = InterpolationMode.HighQualityBicubic;

            // pre paint white to the background of transparent images
            graph.Clear(Color.White);
            graph.DrawImage(image, 0, 0, widthTh, heightTh);

            if (contentType.Contains("pjpeg"))
                contentType = "image/jpeg";

            ImageCodecInfo codec = GetEncoderInfo(contentType);

            if (codec == null)
                codec = FindEncoder(ImageFormat.Jpeg);

            // set image quality
            EncoderParameters eps = new EncoderParameters(1);
            eps = new EncoderParameters();
            eps.Param[0] = new EncoderParameter(Encoder.Quality, 100);

            // Save to the cache
            MemoryStream data = new MemoryStream();
            bitmap.Save(data, codec, eps);

            bitmap.Dispose();
            graph.Dispose();
            eps.Dispose();
            image.Dispose();

            return data.ToArray();
        }



        /// <summary>
        /// Thumbnail va output stream
        /// </summary>
        public static void RewriteImage(Bitmap bmpUpload, int tWidth, int tHeight)
        {
            try
            {
                bool fCopy = false;
                int pWidth = 0;
                int pHeight = 0;
                int iWidth = bmpUpload.Width;
                int iHeight = bmpUpload.Height;

                if (iWidth > 0 && iHeight > 0)
                {
                    if (tHeight > 0) // Thumbnail theo Width
                    {
                        if (iHeight > tHeight)
                        {

                            pHeight = tHeight;
                            double i = (double)iHeight / (double)tHeight;
                            pWidth = Convert.ToInt32((double)iWidth / i);
                        }
                        else
                        {
                            fCopy = true;
                        }
                    }
                    else if (iWidth == iHeight)
                    {
                        pWidth = pHeight = tHeight;
                    }
                    else if (iHeight > 0) // Thumbnail theo Height
                    {
                        pWidth = tWidth;
                        double i = iWidth / tWidth;
                        pHeight = Convert.ToInt32(iHeight / i);
                    }
                }

                if (!fCopy)
                {
                    Bitmap bmpSave = new Bitmap(pWidth, pHeight);

                    Graphics graph;
                    graph = Graphics.FromImage(bmpSave);
                    graph.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    graph.Clear(Color.White);
                    graph.DrawImage(bmpUpload, 0, 0, pWidth, pHeight);
                    //
                    string contentType = "image/jpeg";
                    System.Drawing.Imaging.ImageCodecInfo codec = GetEncoderInfo(contentType);
                    if (codec == null)
                    {
                        codec = FindEncoder(ImageFormat.Jpeg);
                    }
                    // 
                    System.Drawing.Imaging.EncoderParameters eps = new System.Drawing.Imaging.EncoderParameters();
                    eps.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);

                    bmpSave.Save(System.Web.HttpContext.Current.Response.OutputStream, codec, eps);
                    bmpSave.Dispose();
                    //
                    //Finish
                    //
                    //bmpUpload.Dispose();
                    graph.Dispose();
                    eps.Dispose();
                }
            }
            catch (Exception ex)
            {
                string err = ex.ToString();
            }
        }

        public static bool RewriteImage(Bitmap bmpUpload, int tWidth, int tHeight, string filename)
        {
            try
            {
                bool fCopy = false;
                int pWidth = 0;
                int pHeight = 0;
                int iWidth = bmpUpload.Width;
                int iHeight = bmpUpload.Height;
                if (iWidth > iHeight && tWidth == tHeight)
                {
                    tHeight = 0;
                }
                else if (iHeight > iWidth && tWidth == tHeight)
                {
                    tWidth = 0;
                }

                if (iWidth > 0 && iHeight > 0)
                {
                    if (tWidth > 0) // Thumbnail theo Width
                    {
                        if (iWidth > tWidth)
                        {

                            pWidth = tWidth;
                            double i = (double)iWidth / (double)tWidth;
                            pHeight = Convert.ToInt32((double)iHeight / i);
                        }
                        else
                        {
                            fCopy = true;
                        }
                    }
                    else if (iWidth == iHeight)
                    {
                        pWidth = pHeight = tHeight;
                    }
                    else if (iHeight > 0) // Thumbnail theo Height
                    {
                        pHeight = tHeight;
                        double i = iHeight / tHeight;
                        pWidth = Convert.ToInt32(iWidth / i);
                    }
                }

                if (!fCopy)
                {
                    Bitmap bmpSave = new Bitmap(pWidth, pHeight);

                    Graphics graph;
                    graph = Graphics.FromImage(bmpSave);
                    graph.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    graph.Clear(Color.White);
                    graph.DrawImage(bmpUpload, 0, 0, pWidth, pHeight);
                    //
                    string contentType = "image/jpeg";
                    System.Drawing.Imaging.ImageCodecInfo codec = GetEncoderInfo(contentType);
                    if (codec == null)
                    {
                        codec = FindEncoder(ImageFormat.Jpeg);
                    }
                    // 
                    System.Drawing.Imaging.EncoderParameters eps = new System.Drawing.Imaging.EncoderParameters();
                    eps.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);

                    bmpSave.Save(filename, codec, eps);
                    bmpSave.Dispose();
                    //
                    //Finish
                    //
                    //bmpUpload.Dispose();
                    graph.Dispose();
                    eps.Dispose();
                    return true;
                }
                else
                {
                    bmpUpload.Save(filename);
                    return false;
                }
            }
            catch (Exception ex)
            {
                string err = ex.ToString();
                return false;
            }
        }

        public static Image ScaleCrop(Image imgPhoto, int Width, int Height, AnchorPosition Anchor, bool IsCrop, bool IsThumbWidthOrHeight)
        {
            if (Width <= 0 && Height <= 0)
            {
                return imgPhoto;
            }

            int sourceWidth = imgPhoto.Width;
            int sourceHeight = imgPhoto.Height;
            int sourceX = 0;
            int sourceY = 0;
            int destX = -1;
            int destY = -1;
            int destWidth = 0;
            int destHeight = 0;


            float nPercent = 0;
            float nPercentW = 0;
            float nPercentH = 0;
            int nPercentAdd = 2; // tang % kich thuoc hinh sau khi scale
            if (Width < 150 & Height < 150)
            {
                nPercentAdd = 5;
            } if (Width < 30 & Height < 30)
            {
                nPercentAdd = 10;
            }

            nPercentW = ((float)Width / (float)sourceWidth);
            nPercentH = ((float)Height / (float)sourceHeight);

            if (IsCrop)
            {
                // ===== scale and crop
                if (nPercentH < nPercentW)
                {
                    nPercent = nPercentW + ((nPercentW / 100) * nPercentAdd);
                    switch (Anchor)
                    {
                        case AnchorPosition.Top:
                            destY = -1;
                            break;
                        case AnchorPosition.Bottom:
                            destY = (int)(Height - (sourceHeight * nPercent)) + 1;
                            break;
                        default:
                            destY = (int)((Height - (sourceHeight * nPercent)) / 2);
                            break;
                    }
                }
                else
                {
                    nPercent = nPercentH + ((nPercentH / 100) * nPercentAdd);
                    switch (Anchor)
                    {
                        case AnchorPosition.Left:
                            destX = -1;
                            break;
                        case AnchorPosition.Right:
                            destX = (int)(Width - (sourceWidth * nPercent)) + 1;
                            break;
                        default:
                            destX = (int)((Width - (sourceWidth * nPercent)) / 2);
                            break;
                    }
                }
                destWidth = (int)(sourceWidth * nPercent);
                destHeight = (int)(sourceHeight * nPercent);
            }
            else
            {
                // ===== only scale
                if (Width == 0)
                {
                    Width = (int)(sourceWidth * nPercentH);

                    nPercent = nPercentH + ((nPercentH / 100) * nPercentAdd);
                    destWidth = (int)(sourceWidth * nPercent);
                    destHeight = (int)(sourceHeight * nPercent);
                }
                else if (Height == 0)
                {
                    Height = (int)(sourceHeight * nPercentW);

                    nPercent = nPercentW + ((nPercentW / 100) * nPercentAdd);
                    destWidth = (int)(sourceWidth * nPercent);
                    destHeight = (int)(sourceHeight * nPercent);

                }
                else
                {

                    if (nPercentH < nPercentW)
                    {
                        // width
                        if (IsThumbWidthOrHeight)
                        {
                            Height = (int)(sourceHeight * nPercentW);
                            nPercent = nPercentW + ((nPercentW / 100) * nPercentAdd);
                            destWidth = (int)(sourceWidth * nPercent);
                            destHeight = (int)(sourceHeight * nPercent);
                        }
                        else
                        {
                            Width = (int)(sourceWidth * nPercentH);
                            nPercent = nPercentH + ((nPercentH / 100) * nPercentAdd);
                            destWidth = (int)(sourceWidth * nPercent);
                            destHeight = (int)(sourceHeight * nPercent);
                        }
                    }
                    else
                    {
                        // height

                        if (IsThumbWidthOrHeight)
                        {
                            Width = (int)(sourceWidth * nPercentH);
                            nPercent = nPercentH + ((nPercentH / 100) * nPercentAdd);
                            destWidth = (int)(sourceWidth * nPercent);
                            destHeight = (int)(sourceHeight * nPercent);
                        }
                        else
                        {
                            Height = (int)(sourceHeight * nPercentW);
                            nPercent = nPercentW + ((nPercentW / 100) * nPercentAdd);
                            destWidth = (int)(sourceWidth * nPercent);
                            destHeight = (int)(sourceHeight * nPercent);
                        }
                    }
                }
            }

            Bitmap bmPhoto = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);

            bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
            Graphics grPhoto = Graphics.FromImage(bmPhoto);
            grPhoto.Clear(Color.Red);
            grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
            grPhoto.DrawImage(imgPhoto,
                new Rectangle(destX, destY, destWidth, destHeight),
                new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
                GraphicsUnit.Pixel);
            grPhoto.Dispose();

            return bmPhoto;
        }
        /// <summary>
        /// Gets the encoder information for the specified mimetype.  Used in imagescaling
        /// </summary>
        /// <param name="mimeType">The mimetype of the picture.</param>
        public static ImageCodecInfo GetEncoderInfo(string mimeType)
        {
            ImageCodecInfo[] myEncoders = ImageCodecInfo.GetImageEncoders();

            foreach (ImageCodecInfo myEncoder in myEncoders)
            {
                if (myEncoder.MimeType == mimeType)
                {
                    return myEncoder;
                }
            }
            return null;
        }

        internal static ImageCodecInfo FindEncoder(ImageFormat format)
        {
            ImageCodecInfo[] infoArray1 = ImageCodecInfo.GetImageEncoders();
            ImageCodecInfo[] infoArray2 = infoArray1;
            for (int num1 = 0; num1 < infoArray2.Length; num1++)
            {
                ImageCodecInfo info1 = infoArray2[num1];
                if (info1.FormatID.Equals(format.Guid))
                {
                    return info1;
                }
            }
            return null;
        }
        public static bool IsValidImage()
        {
            /*FileInfo finfo = new FileInfo(Server.MapPath(MyFile));
            long FileInBytes = finfo.Length;
            long FileInKB = finfo.Length / 1024;*/
            return true;

        }
        public static bool IsValidVideo()
        {
            return true;
        }
        public static ImageFormat GetFormatResizeImage(string newFormat)
        {
            //jpg|.jpeg|.png|.gif|.bmp
            switch (newFormat.ToLower())
            {
                case ".gif":
                    {
                        return ImageFormat.Gif;
                    }
                case ".bmp":
                    {
                        return ImageFormat.Bmp;
                    }
                case ".emf":
                    {
                        return ImageFormat.Emf;
                    }
                case ".exif":
                    {
                        return ImageFormat.Exif;
                    }
                case ".icon":
                    {
                        return ImageFormat.Icon;
                    }
                case ".jpeg":
                    {
                        return ImageFormat.Jpeg;
                    }
                case ".memoryBmp":
                    {
                        return ImageFormat.MemoryBmp;
                    }
                case ".png":
                    {
                        return ImageFormat.Png;
                    }
                case ".tiff":
                    {
                        return ImageFormat.Tiff;
                    }
                case ".wmf":
                    {
                        return ImageFormat.Wmf;
                    }
                default:
                    return ImageFormat.Jpeg;
            }
        }
        public static void ResizeImageFile(string fileName, string newFileName, int targetSize, ImageFormat imgFormat)
        {
            using (System.Drawing.Image oldImage = System.Drawing.Image.FromFile(fileName))
            {
                Size newSize = CalculateDimensions(oldImage.Size, targetSize);
                using (Bitmap newImage = new Bitmap(newSize.Width, newSize.Height, PixelFormat.Format24bppRgb))
                {
                    using (Graphics canvas = Graphics.FromImage(newImage))
                    {
                        canvas.SmoothingMode = SmoothingMode.AntiAlias;
                        canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
                        canvas.DrawImage(oldImage, new Rectangle(new Point(0, 0), newSize));
                        newImage.Save(newFileName, imgFormat);
                    }
                }
            }
        }
        private static Size CalculateDimensions(Size oldSize, int targetSize)
        {
            Size newSize = new Size();
            if (oldSize.Height > oldSize.Width)
            {
                newSize.Width = (int)(oldSize.Width * ((float)targetSize / (float)oldSize.Height));
                newSize.Height = targetSize;
            }
            else
            {
                newSize.Width = targetSize;
                newSize.Height = (int)(oldSize.Height * ((float)targetSize / (float)oldSize.Width));
            }
            return newSize;
        }
        public static string ConvertLinkVideoToImage(string link)
        {
            ////p://www.youtube.com/watch?v=MRY-weqyHus&feature=related
            string result = "http://i1.ytimg.com/vi/{0}/default.jpg";
            int indexPara = link.LastIndexOf("?v=");
            if (indexPara > 0)
            {
                string value = string.Empty;
                int indexQ = link.IndexOf("&");
                if (indexQ > 0)
                    value = link.Substring(indexPara + 3, indexQ - indexPara - 3);
                else value = link.Substring(indexPara + 3, link.Length - indexPara - 3);
                result = string.Format(result,value);

            }
            return result;
        }
        public static Image Crop(Image imgPhoto, int Width, int Height, AnchorPosition Anchor)
        {
            int sourceWidth = imgPhoto.Width;
            int sourceHeight = imgPhoto.Height;
            int sourceX = 0;
            int sourceY = 0;
            int destX = 0;
            int destY = 0;

            float nPercent = 0;
            float nPercentW = 0;
            float nPercentH = 0;

            nPercentW = ((float)Width / (float)sourceWidth);
            nPercentH = ((float)Height / (float)sourceHeight);

            if (nPercentH < nPercentW)
            {
                nPercent = nPercentW;
                switch (Anchor)
                {
                    case AnchorPosition.Top:
                        destY = 0;
                        break;
                    case AnchorPosition.Bottom:
                        destY = (int)(Height - (sourceHeight * nPercent));
                        break;
                    default:
                        destY = (int)((Height - (sourceHeight * nPercent)) / 2);
                        break;
                }
            }
            else
            {
                nPercent = nPercentH;
                switch (Anchor)
                {
                    case AnchorPosition.Left:
                        destX = 0;
                        break;
                    case AnchorPosition.Right:
                        destX = (int)(Width - (sourceWidth * nPercent));
                        break;
                    default:
                        destX = (int)((Width - (sourceWidth * nPercent)) / 2);
                        break;
                }
            }

            int destWidth = (int)(sourceWidth * nPercent);
            int destHeight = (int)(sourceHeight * nPercent);

            Bitmap bmPhoto = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);

            bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
            Graphics grPhoto = Graphics.FromImage(bmPhoto);
            grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;

            grPhoto.DrawImage(imgPhoto,
            new Rectangle(destX, destY, destWidth, destHeight),
            new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
            GraphicsUnit.Pixel);
            grPhoto.Dispose();
            return bmPhoto;
        }
        public static ImageFormat GetImageFormat(string file)
        {
            if (file == string.Empty)
                return ImageFormat.Jpeg;
            try
            {
                file = file.ToLower().Trim();
                if (!file.Contains("."))
                    return ImageFormat.Jpeg;
                int index = file.LastIndexOf(".");
                string ext = file.Substring(index + 1, file.Length - 1 - index);
                switch (ext)
                {
                    case "gif":
                        {
                            return ImageFormat.Gif;
                            break;
                        }
                    case "icon":
                        {
                            return ImageFormat.Icon;
                            break;
                        }
                    case "png":
                        {
                            return ImageFormat.Png;
                            break;
                        }
                    default:
                        {
                            return ImageFormat.Jpeg;
                        }
                }
            }
            catch
            {
            }
            return ImageFormat.Jpeg;
        }
    }
}